package com.util.moduleManager 
{
	import com.boyaa.fly.Timepiece;
	import com.boyaa.shells.control.EventCenter;
	import com.boyaa.shells.core.BattlefieldManager;
	import com.boyaa.shells.events.GameEvent;
	import com.boyaa.shells.net.Remoting;
	import com.boyaa.shells.view.duplicateroom.event.DuplicateEvent;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	
	/**
	 * 单个资源或资源序列加载
	 * @author Heineken
	 */
	public class Module extends EventDispatcher
	{
		private var _loader:Loader = null;
		private var _callBack:Function = null;
		private var _funObj:Object = null;
		private var _tepPaths:Array = null;
		private var _path:String = "";
		private var _loadCount:int = 0;			//单个资源请求加载次数(用于解决CDN有时请求资源加载失败的问题)
		
		public function Module(paths:*, ...rest) 
		{
			_tepPaths = [];
			if(rest[0])
				_callBack = rest[0];
			if (rest[1])
				_funObj = rest[1];
			
			if (paths is Array)
				_tepPaths = paths;
			else
				_tepPaths.push(paths);
			
			_loader = new Loader();
			_path = _tepPaths.pop();
			_loadCount = 1;
			loadModule();
		}
		
		private function loadModule():void
		{
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
			_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			_loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			
			_loader.load(new URLRequest(_path), new LoaderContext(true, ApplicationDomain.currentDomain));
		}
		
		protected function onCompleteHandler(event:Event):void
		{
			_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onCompleteHandler);
			_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgressHandler);
			_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			_loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			
			//派發開始副本資源加載進度事件
			if (BattlefieldManager.instance.battlefieldType == 3)
			{
				EventCenter.DuplicateEvent.dispatchEvent(new DuplicateEvent(DuplicateEvent.COPY_PROGRESSING));
			}
			
			ModuleManager.getInstance().dispatchEvent(new Event(ModuleManager.READY));
			//ModuleManager.modules.push(_loader.contentLoaderInfo.url);
			
			if (_tepPaths.length != 0)
			{
				_path = _tepPaths.pop();
				_loadCount = 1;
				loadModule();
			}
			else if (_tepPaths.length == 0)
			{
				if (_callBack != null)
				{
					_callBack.apply(_funObj);
					remove();
				}
			}
		}
		
		protected function onProgressHandler(event:ProgressEvent):void
		{
			var num:int = event.bytesLoaded * 100 / event.bytesTotal;
			ModuleManager.getInstance().dispatchEvent(new Event(ModuleManager.PROGRESSING));
			EventCenter.GameEvent.dispatchEvent(new GameEvent(GameEvent.LOADMODULE_PROGRESS, num));
		}
		
		private function ioErrorHandler(event:IOErrorEvent):void
		{
			_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onCompleteHandler);
			_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgressHandler);
			_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			_loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			
			//用于解决CDN有时请求资源加载失败的问题 1次请求失败就继续请求，超过3次还是失败则抛出错误
			if (_loadCount > 3)
			{
				remove();
				
				var str:String = "Module IOErrorEvent::" + _path
				throw new Error(str);
			}
			else
			{
				Timepiece.instance.addDelayCall(reLoadModule, 1000);
			}
		}
		
		private function reLoadModule():void 
		{
			Timepiece.instance.removeFun(reLoadModule, 2);
			_loadCount++;
			loadModule();
		}
		
		protected function securityErrorHandler(event:SecurityErrorEvent):void
		{
			_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onCompleteHandler);
			_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgressHandler);
			_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			_loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			remove();
			
			var str:String = "Module SecurityErrorEvent::" + _path;
			throw new Error(str);
		}
		
		private function remove():void
		{
			_loader = null;
			_callBack = null;
			_funObj = null;
			_tepPaths = null;
		}
	}
}